import { EventEmitter } from 'events';

export interface ConnectionConfig {
  serverUrl: string;
  deviceId: string;
  reconnectAttempts?: number;
  reconnectDelay?: number;
  heartbeatInterval?: number;
}

export interface ConnectionStatus {
  sse: 'connected' | 'connecting' | 'disconnected' | 'error';
  websocket: 'connected' | 'connecting' | 'disconnected' | 'error';
  overall: 'connected' | 'connecting' | 'disconnected' | 'error';
}

export class HybridConnectionService extends EventEmitter {
  private config: ConnectionConfig;
  private sseConnection: EventSource | null = null;
  private wsConnection: WebSocket | null = null;
  private reconnectAttempts = 0;
  private heartbeatTimer: NodeJS.Timeout | null = null;
  private status: ConnectionStatus = {
    sse: 'disconnected',
    websocket: 'disconnected',
    overall: 'disconnected'
  };

  constructor(config: ConnectionConfig) {
    super();
    this.config = {
      reconnectAttempts: 5,
      reconnectDelay: 1000,
      heartbeatInterval: 30000,
      ...config
    };
  }

  // 建立混合连接
  async connect(): Promise<void> {
    console.log('开始建立混合连接...');
    
    try {
      // 同时建立SSE和WebSocket连接
      await Promise.all([
        this.connectSSE(),
        this.connectWebSocket()
      ]);
      
      this.updateOverallStatus();
      this.startHeartbeat();
      console.log('混合连接建立成功');
    } catch (error) {
      console.error('混合连接建立失败:', error);
      throw error;
    }
  }

  // 连接SSE
  private async connectSSE(): Promise<void> {
    return new Promise((resolve, reject) => {
      const clientId = `mobile-${this.config.deviceId}-${Date.now()}`;
      const url = `${this.config.serverUrl}/api/sse/connect?deviceId=${this.config.deviceId}&clientId=${clientId}`;
      
      this.status.sse = 'connecting';
      this.emit('status-change', this.status);
      
      this.sseConnection = new EventSource(url);

      this.sseConnection.onopen = () => {
        console.log('SSE连接已建立');
        this.status.sse = 'connected';
        this.emit('status-change', this.status);
        this.setupSSEEventListeners();
        resolve();
      };

      this.sseConnection.onerror = (error) => {
        console.error('SSE连接错误:', error);
        this.status.sse = 'error';
        this.emit('status-change', this.status);
        reject(error);
      };
    });
  }

  // 连接WebSocket
  private async connectWebSocket(): Promise<void> {
    return new Promise((resolve, reject) => {
      const wsUrl = this.config.serverUrl.replace(/^https?:\/\//, 'ws://') + '/socket.io/?EIO=4&transport=websocket';
      
      this.status.websocket = 'connecting';
      this.emit('status-change', this.status);
      
      this.wsConnection = new WebSocket(wsUrl);

      this.wsConnection.onopen = () => {
        console.log('WebSocket连接已建立');
        this.status.websocket = 'connected';
        this.emit('status-change', this.status);
        this.setupWebSocketEventListeners();
        this.registerDevice();
        resolve();
      };

      this.wsConnection.onerror = (error) => {
        console.error('WebSocket连接错误:', error);
        this.status.websocket = 'error';
        this.emit('status-change', this.status);
        reject(error);
      };

      this.wsConnection.onclose = () => {
        console.log('WebSocket连接关闭');
        this.status.websocket = 'disconnected';
        this.emit('status-change', this.status);
        this.handleReconnect();
      };
    });
  }

  // 设置SSE事件监听
  private setupSSEEventListeners(): void {
    if (!this.sseConnection) return;

    // 语音文字接收
    this.sseConnection.addEventListener('voice:text', (event) => {
      try {
        const data = JSON.parse(event.data);
        this.emit('voice:text', data);
      } catch (error) {
        console.error('解析SSE语音文字事件失败:', error);
      }
    });

    // 配对状态更新
    this.sseConnection.addEventListener('pairing:status', (event) => {
      try {
        const data = JSON.parse(event.data);
        this.emit('pairing:status', data);
      } catch (error) {
        console.error('解析SSE配对状态事件失败:', error);
      }
    });

    // 文字接收
    this.sseConnection.addEventListener('text:receive', (event) => {
      try {
        const data = JSON.parse(event.data);
        this.emit('text:receive', data);
      } catch (error) {
        console.error('解析SSE文字接收事件失败:', error);
      }
    });

    // 系统消息
    this.sseConnection.addEventListener('system:message', (event) => {
      try {
        const data = JSON.parse(event.data);
        this.emit('system:message', data);
      } catch (error) {
        console.error('解析SSE系统消息事件失败:', error);
      }
    });

    // 连接确认
    this.sseConnection.addEventListener('connection:established', (event) => {
      try {
        const data = JSON.parse(event.data);
        console.log('SSE连接确认:', data);
      } catch (error) {
        console.error('解析SSE连接确认事件失败:', error);
      }
    });

    // 心跳
    this.sseConnection.addEventListener('heartbeat', (event) => {
      try {
        const data = JSON.parse(event.data);
        console.log('收到SSE心跳:', data);
      } catch (error) {
        console.error('解析SSE心跳事件失败:', error);
      }
    });
  }

  // 设置WebSocket事件监听
  private setupWebSocketEventListeners(): void {
    if (!this.wsConnection) return;

    this.wsConnection.onmessage = (event) => {
      try {
        const data = event.data;
        
        // Socket.io协议处理
        if (typeof data === 'string') {
          if (data.startsWith('0')) {
            // Socket.io握手响应
            return;
          }
          if (data.startsWith('42')) {
            // Socket.io事件消息
            const jsonData = data.substring(2);
            const [eventName, eventData] = JSON.parse(jsonData);
            this.emit(eventName, eventData);
            return;
          }
          if (data === '2') {
            // 心跳消息
            this.wsConnection?.send('3'); // 回复心跳
            return;
          }
        }
      } catch (error) {
        console.error('处理WebSocket消息失败:', error);
      }
    };
  }

  // 注册设备
  private registerDevice(): void {
    if (!this.wsConnection) return;

    const deviceInfo = {
      type: 'mobile',
      name: 'Mobile Device',
      capabilities: {
        canReceiveText: true,
        canSendVoice: true,
        canGenerateQR: false,
        canScanQR: true
      }
    };

    // 发送Socket.io握手
    this.wsConnection.send('40'); // Socket.io namespace connect
    
    // 注册设备
    setTimeout(() => {
      this.wsConnection?.send('42["device:register",' + JSON.stringify(deviceInfo) + ']');
    }, 1000);
  }

  // 发送消息
  send(event: string, data: any): void {
    // 根据事件类型选择传输方式
    if (this.shouldUseWebSocket(event)) {
      this.sendViaWebSocket(event, data);
    } else {
      this.sendViaAPI(event, data);
    }
  }

  // 判断是否应该使用WebSocket
  private shouldUseWebSocket(event: string): boolean {
    // 语音流数据必须使用WebSocket
    if (event.startsWith('voice:stream')) {
      return true;
    }
    
    // 实时配对协商使用WebSocket
    if (event.startsWith('pairing:negotiate')) {
      return true;
    }
    
    // 其他消息使用HTTP API
    return false;
  }

  // 通过WebSocket发送消息
  private sendViaWebSocket(event: string, data: any): void {
    if (this.wsConnection && this.status.websocket === 'connected') {
      const message = `42["${event}",${JSON.stringify(data)}]`;
      this.wsConnection.send(message);
    } else {
      console.warn('WebSocket未连接，无法发送消息:', event);
    }
  }

  // 通过HTTP API发送消息
  private async sendViaAPI(event: string, data: any): Promise<void> {
    try {
      const response = await fetch(`${this.config.serverUrl}/api/message`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          event,
          data,
          deviceId: this.config.deviceId,
          timestamp: Date.now()
        })
      });
      
      if (!response.ok) {
        throw new Error(`API请求失败: ${response.status}`);
      }
    } catch (error) {
      console.error('API发送消息失败:', error);
      this.emit('sendError', { event, data, error });
    }
  }

  // 发送语音流数据
  sendVoiceStream(audioChunk: ArrayBuffer): void {
    this.sendViaWebSocket('voice:stream/data', {
      audioData: audioChunk,
      timestamp: Date.now()
    });
  }

  // 开始语音流
  startVoiceStream(params?: any): void {
    this.sendViaWebSocket('voice:stream/start', params || {});
  }

  // 结束语音流
  endVoiceStream(): void {
    this.sendViaWebSocket('voice:stream/end', {});
  }

  // 语音识别
  async recognizeSpeech(audioData: string, language: string): Promise<any> {
    const response = await fetch(`${this.config.serverUrl}/api/voice/recognize`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ audioData, language, deviceId: this.config.deviceId })
    });
    
    if (!response.ok) {
      throw new Error(`语音识别请求失败: ${response.status}`);
    }
    
    return response.json();
  }

  // 发送文字
  async sendText(text: string, targetDeviceId: string): Promise<any> {
    const response = await fetch(`${this.config.serverUrl}/api/text/send`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ text, deviceId: this.config.deviceId, targetDeviceId })
    });
    
    if (!response.ok) {
      throw new Error(`发送文字请求失败: ${response.status}`);
    }
    
    return response.json();
  }

  // 开始心跳
  private startHeartbeat(): void {
    this.heartbeatTimer = setInterval(() => {
      if (this.status.overall === 'connected') {
        this.sendViaWebSocket('system:heartbeat', { timestamp: Date.now() });
      }
    }, this.config.heartbeatInterval);
  }

  // 更新整体状态
  private updateOverallStatus(): void {
    if (this.status.sse === 'connected' || this.status.websocket === 'connected') {
      this.status.overall = 'connected';
    } else if (this.status.sse === 'connecting' || this.status.websocket === 'connecting') {
      this.status.overall = 'connecting';
    } else if (this.status.sse === 'error' || this.status.websocket === 'error') {
      this.status.overall = 'error';
    } else {
      this.status.overall = 'disconnected';
    }
    
    this.emit('status-change', this.status);
  }

  // 处理重连
  private handleReconnect(): void {
    if (this.reconnectAttempts < this.config.reconnectAttempts!) {
      this.reconnectAttempts++;
      const delay = this.config.reconnectDelay! * this.reconnectAttempts;
      
      console.log(`尝试重连 (${this.reconnectAttempts}/${this.config.reconnectAttempts})`);
      
      setTimeout(() => {
        this.connect().catch(console.error);
      }, delay);
    } else {
      console.error('重连次数已达上限');
      this.emit('reconnect-failed');
    }
  }

  // 断开连接
  disconnect(): void {
    console.log('断开混合连接...');
    
    if (this.sseConnection) {
      this.sseConnection.close();
      this.sseConnection = null;
    }
    
    if (this.wsConnection) {
      this.wsConnection.close();
      this.wsConnection = null;
    }
    
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer);
      this.heartbeatTimer = null;
    }
    
    this.status = {
      sse: 'disconnected',
      websocket: 'disconnected',
      overall: 'disconnected'
    };
    
    this.emit('status-change', this.status);
    console.log('混合连接已断开');
  }

  // 获取连接状态
  getConnectionStatus(): ConnectionStatus {
    return { ...this.status };
  }

  // 检查是否连接
  isConnected(): boolean {
    return this.status.overall === 'connected';
  }
} 